package com.cleaningcloud.erp.service.impl;

import com.cleaningcloud.common.core.utils.DateUtils;
import com.cleaningcloud.common.core.utils.UniqueIdUtils;
import com.cleaningcloud.common.security.utils.CommunityTypeConversionUtils;
import com.cleaningcloud.common.security.utils.SecurityUtils;
import com.cleaningcloud.erp.api.domain.ErpCustomer;
import com.cleaningcloud.erp.domain.*;
import com.cleaningcloud.erp.domain.dto.ErpSaleDto;
import com.cleaningcloud.erp.domain.statistics.SummaryStock;
import com.cleaningcloud.erp.domain.vo.ErpAccountsReceivableVo;
import com.cleaningcloud.erp.domain.vo.ErpOutboundVo;
import com.cleaningcloud.erp.domain.vo.ErpSaleDetailsVo;
import com.cleaningcloud.erp.domain.vo.ErpSaleVo;
import com.cleaningcloud.erp.mapper.*;
import com.cleaningcloud.erp.service.IErpSaleService;
import com.cleaningcloud.erp.utils.ProcureSaleUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 销售单Service业务层处理
 *
 * @author cleaningcloud
 * @date 2024-10-02
 */
@Service
public class ErpSaleServiceImpl implements IErpSaleService {
    @Autowired
    private ErpSaleMapper erpSaleMapper;

    @Autowired
    private ErpOutboundMapper erpOutboundMapper;

    @Autowired
    private ErpAccountsReceivableMapper erpAccountsReceivableMapper;

    @Autowired
    private ErpCommodityUnitMapper erpCommodityUnitMapper;

    @Autowired
    private ErpCustomerMapper erpCustomerMapper;

    @Autowired
    private ErpWareHouseMapper erpWareHouseMapper;

    /**
     * 查询销售单
     *
     * @param saleId 销售单主键
     * @return 销售单
     */
    @Override
    public ErpSaleVo selectErpSaleBySaleId(Long saleId) {
        ErpSaleVo saleVo = erpSaleMapper.selectErpSaleBySaleId(saleId);
        for (ErpSaleDetailsVo erpSaleDetailsVo : saleVo.getDetailsList()) {
            erpSaleDetailsVo.setCommodityType(CommunityTypeConversionUtils.conversion(erpSaleDetailsVo.getCommodityType()));
        }
        return saleVo;
    }

    /**
     * 查询销售单列表
     *
     * @param erpSale 销售单
     * @return 销售单
     */
    @Override
    public List<ErpSaleVo> selectErpSaleList(ErpSaleDto erpSale) {
        return erpSaleMapper.selectErpSaleList(erpSale);
    }

    /**
     * 新增销售单
     *
     * @param erpSale 销售单
     * @return 结果
     */
    @Override
    @Transactional
    public int insertErpSale(ErpSaleDto erpSale) {
        erpSale.setCreateTime(DateUtils.getNowDate());
        erpSale.setCreateId(SecurityUtils.getUserId());
        erpSale.setCreateName(SecurityUtils.getUsername());
        erpSale.setFlag("Y");
        erpSale.setLogisticsStauts("0");
        erpSale.setSaleBatch(0);
        erpSale.setSaleOdd("XS" + UniqueIdUtils.generateUniqueId());
        erpSaleMapper.insertErpSale(erpSale);
        // 新增销售明细表
        if (erpSale.getDetailsList() != null && !erpSale.getDetailsList().isEmpty()) {
            erpSale.getDetailsList().forEach(item -> {
                item.setSaleId(erpSale.getSaleId());
                item.setSaleOdd(erpSale.getSaleOdd());
                item.setWareId(item.getOutWareId());
            });
            erpSaleMapper.batchSaleDetailsInsert(erpSale.getDetailsList());
        }
        return 1;
    }

    /**
     * 修改销售单
     *
     * @param erpSale 销售单
     * @return 结果
     */
    @Override
    @Transactional
    public int updateErpSale(ErpSaleDto erpSale) {
        // 删除之前绑定的销售明细数据
        erpSaleMapper.deleteSaleDetailsBySaleId(erpSale.getSaleId());
        // 新增销售明细
        if (erpSale.getDetailsList() != null && !erpSale.getDetailsList().isEmpty()) {
            erpSale.getDetailsList().forEach(item -> {
                item.setSaleId(erpSale.getSaleId());
                item.setSaleOdd(erpSale.getSaleOdd());
                item.setWareId(item.getOutWareId());
            });
            erpSaleMapper.batchSaleDetailsInsert(erpSale.getDetailsList());
        }
        return erpSaleMapper.updateErpSale(erpSale);
    }

    @Override
    public int logistics(ErpSaleDto erpSaleDto) {
        return erpSaleMapper.updateErpSale(erpSaleDto);
    }

    /**
     * 批量删除销售单
     *
     * @param saleIds 需要删除的销售单主键
     * @return 结果
     */
    @Override
    public int deleteErpSaleBySaleIds(Long[] saleIds) {
        return erpSaleMapper.deleteErpSaleBySaleIds(saleIds);
    }

    /**
     * 删除销售单信息
     *
     * @param saleId 销售单主键
     * @return 结果
     */
    @Override
    public int deleteErpSaleBySaleId(Long saleId) {
        return erpSaleMapper.deleteErpSaleBySaleId(saleId);
    }

    /**
     * @Author Shaw
     * @Description 审核销售单
     * @date: 2025-10-28 10:00
     * @param: //TODO
     */
    @Override
    public int auditSale(ErpSale erpSale) {
        ErpSaleVo sale = erpSaleMapper.selectErpSaleBySaleId(erpSale.getSaleId());
        if (sale == null) {
            throw new RuntimeException("销售单查询失败！");
        }
        sale.setSaleStatus(erpSale.getSaleStatus());
        // 审核通过时 修改销售批次数量 + 1
        if (erpSale.getSaleStatus() == 2) {
            // 查询该客户已审核通过的销售单
            int saleBatch = erpSaleMapper.queryApprovedByCustomerId(sale.getCustomerId());
            erpSale.setSaleBatch(saleBatch + 1);
            // 生成应付款单数据
            ErpAccountsReceivable erpAccountsReceivable = new ErpAccountsReceivable();
            erpAccountsReceivable.setOddNo(sale.getSaleOdd());
            erpAccountsReceivable.setOddType(1);
            erpAccountsReceivable.setBusinessId(sale.getCustomerId());
            erpAccountsReceivable.setOddDate(DateUtils.getNowDate());
            erpAccountsReceivable.setOddStatus(0);
            erpAccountsReceivable.setOddSumMoney(sale.getPayAmount());
            erpAccountsReceivable.setFlag("Y");
            erpAccountsReceivableMapper.insertErpAccountsReceivable(erpAccountsReceivable);
            // 生成出库单
            // 计算应出库总量
            int answerScheduledReceipt = (int) sale.getDetailsList()
                    .stream()
                    .mapToDouble(ErpSaleDetails::getSaleNumber)
                    .sum();
            // 销售出库单字段赋值
            ErpOutbound erpOutbound = ProcureSaleUtils.setOutboundFields(erpAccountsReceivable, sale.getWareId(), answerScheduledReceipt);
            erpOutboundMapper.insertErpOutbound(erpOutbound);
            // 销售出库明细
            List<ErpOutboundDetails> erpOutboundDetailsList = ProcureSaleUtils.getErpOutboundDetails(sale.getDetailsList(), erpOutbound);
            if (!erpOutboundDetailsList.isEmpty()) {
                erpOutboundMapper.batchOutboundDetailsInsert(erpOutboundDetailsList);
            }
        } else {
            erpSale.setRejectReason(erpSale.getRejectReason());
            erpSale.setRejectTime(new Date());
        }
        sale.setApproveId(SecurityUtils.getUserId());
        sale.setApproveName(SecurityUtils.getUsername());
        sale.setApproveTime(DateUtils.getNowDate());
        return erpSaleMapper.updateErpSale(sale);
    }

    @Override
    public List<SummaryStock> getSummaryStock(SummaryStock summaryStock) {
        List<SummaryStock> list = erpSaleMapper.getSummaryStock(summaryStock);
        for (SummaryStock stock : list) {
            stock.setCommodityType(CommunityTypeConversionUtils.conversion(stock.getCommodityType()));
        }
        return list;
    }


    /**
     * @Author Shaw
     * @Description 三才环科商城(小程序)用户下单
     * @date: 2025-04-03 9:35
     * @param: //TODO
     */
    @Override
    @Transactional
    public int insertMallErpSale(ErpSaleDto erpSale) {
        erpSale.setSaleOdd("XS" + UniqueIdUtils.generateUniqueId());
        erpSale.setWareId(5L);//三才仓库
        erpSale.setSaleTime(DateUtils.getNowDate());//下单时间
        erpSale.setSaleId(erpSale.getCustomerId());//下单人
        erpSale.setLogisticsMethod(1L);//默认按重量
        erpSale.setLogisticsStauts("0");//默认未发货
        erpSale.setCreateId(erpSale.getCustomerId());
        erpSale.setCreateTime(DateUtils.getNowDate());
        erpSale.setCreateName(erpSale.getCustomerName());
        erpSale.setFlag("Y");
        erpSale.setSaleBatch(1);
        BigDecimal rateMoney = BigDecimal.valueOf(0.00);//销售利润
        // 新增销售明细表
        if (erpSale.getDetailsList() != null && !erpSale.getDetailsList().isEmpty()) {
            erpSale.getDetailsList().forEach(item -> {
                item.setSaleId(erpSale.getSaleId());
                item.setSaleOdd(erpSale.getSaleOdd());
                ErpCommodityUnit ecu = erpCommodityUnitMapper.selectErpCommodityUnitByCommodityUnitId(item.getCommodityUnitId());
                if(null != ecu) {
                    BigDecimal difference = item.getSalePrice().subtract(ecu.getCostPrice()); //销售价-成本价=销售利润
                    rateMoney.add(difference.multiply(BigDecimal.valueOf(item.getSaleNumber()))); //销售利润*销售数量=销售总利润
                }
                ErpCustomer customer = erpCustomerMapper.selectErpCustomerByCustomerId(erpSale.getCustomerId());
                if(null != customer){
                    item.setSaleRate(Double.parseDouble(customer.getDiscount().toString()));
                }
                item.setSubtotal(item.getSalePrice().multiply(BigDecimal.valueOf(item.getSaleNumber())));//小计
            });
            erpSaleMapper.batchSaleDetailsInsert(erpSale.getDetailsList());
        }
        erpSale.setRateMoney(rateMoney);
        return erpSaleMapper.insertErpSale(erpSale);
    }

    /**
     * @Author Shaw
     * @Description 三才环科商城(小程序)获取下单列表
     * @date: 2025-04-03 9:35
     * @param: //TODO
     */
    @Override
    public List<ErpSaleVo> getMallSaleList(ErpSaleDto erpSale){
        ErpSaleDto obj = new ErpSaleDto();
        obj.setCustomerId(erpSale.getCustomerId());
        //订单状态-待发货
        if(erpSale.getOrderStatus() == 1L){
            obj.setLogisticsStauts("0");
            obj.setSaleStatus(2L);
        //订单状态-待收货
        }else if(erpSale.getOrderStatus() == 2L){
            obj.setLogisticsStauts("1");
            obj.setSaleStatus(2L);
        //订单状态-已完成
        }else if(erpSale.getOrderStatus() == 3L){
            obj.setLogisticsStauts("2");
            obj.setSaleStatus(4L);
        //订单状态-已取消
        }else if(erpSale.getOrderStatus() == 4L){
            obj.setSaleStatus(5L);
        }
        List<ErpSaleVo> list = erpSaleMapper.selectErpSaleList(obj);
        if(!list.isEmpty()){
            list.forEach(item -> {
                if(item.getLogisticsStauts().equals("0") && item.getSaleStatus() == 2L){
                    item.setOrderStatusStr("待发货");
                    item.setIsCancel(1);
                }else if(item.getLogisticsStauts().equals("1") && item.getSaleStatus() == 2L){
                    item.setOrderStatusStr("已发货");
                }else if(item.getLogisticsStauts().equals("2") && item.getSaleStatus() == 4L){
                    item.setOrderStatusStr("已完成");
                }else if(item.getSaleStatus() == 5L){
                    item.setOrderStatusStr("已取消");
                }
                ErpSaleDto obj1 = new ErpSaleDto();
                obj1.setSaleId(item.getSaleId());
                List<ErpSaleDetailsVo> detailsList =erpSaleMapper.selectErpSaleDetailsList(obj1);
                if(!detailsList.isEmpty()){
                    int sumNumber = 0;//销售总量
                    for (int i=0;i<detailsList.size();i++){
                        sumNumber += detailsList.get(i).getSaleNumber();
                    }
                    item.setSaleSumNumber(sumNumber);
                    item.setDetailsList(detailsList);
                }
            });
        }
        return erpSaleMapper.selectErpSaleList(erpSale);
    }

    /**
     * @Author Shaw
     * @Description 三才环科商城(小程序)根据订单ID查询订单详情
     * @date: 2025-04-03 9:35
     * @param: //TODO
     */
    @Override
    public ErpSaleVo getMallSaleInfo(ErpSaleDto erpSale){
        ErpSaleVo erpSaleVo = null;
        ErpAccountsReceivable erpAccountsReceivable = new ErpAccountsReceivable();
        erpAccountsReceivable.setOddNo(erpSale.getSaleOdd());
        erpAccountsReceivable.setOddType(1);
        erpAccountsReceivable.setBusinessId(erpSale.getCustomerId());
        ErpAccountsReceivableVo erpAccountsReceivableVo = erpAccountsReceivableMapper.selectErpAccountsReceivableByQueryWhere(erpAccountsReceivable);
        if(null != erpAccountsReceivableVo){
            ErpOutboundVo erpOutboundVo = erpOutboundMapper.selectErpOutboundByReceivableId(erpAccountsReceivableVo.getReceivableId());
            erpSaleVo = erpSaleMapper.getSaleInfoBySaleNo(erpSale.getSaleOdd());
            erpSaleVo.setIsHarvest(erpOutboundVo.getIsHarvest());
            erpSaleVo.setHarvestTime(erpOutboundVo.getHarvestTime().toString());
            erpSaleVo.setHarvestImg(erpOutboundVo.getHarvestImg());
            erpSaleVo.setDeliverTime(erpOutboundVo.getDeliverTime().toString());
            ErpSaleDto erpSaleDto = new ErpSaleDto();
            erpSaleDto.setSaleId(erpSale.getSaleId());
            List<ErpSaleDetailsVo> list = erpSaleMapper.selectErpSaleDetailsList(erpSaleDto);
            if(!list.isEmpty()){
                BigDecimal sumPrice = new BigDecimal(0);
                for (int i=0;i<list.size();i++){
                    ErpSaleDetailsVo erpSaleDetailsVo = list.get(i);
                    //计算合计金额
                    sumPrice.add(BigDecimal.valueOf(erpSaleDetailsVo.getSaleNumber()).multiply(erpSaleDetailsVo.getSalePrice()));
                }
                erpSaleVo.setSumPrice(sumPrice);
                erpSaleVo.setDetailsList(list);
            }
        }
        return erpSaleVo;
    }

    /**
     * @Author Shaw
     * @Description 三才环科商城(小程序)取消订单
     * @date: 2025-04-03 9:35
     * @param: //TODO
     */
    @Override
    @Transactional
    public int cancelOrder(ErpSaleDto erpSale){
        ErpSaleVo erpSaleVo = null;
        ErpAccountsReceivable erpAccountsReceivable = new ErpAccountsReceivable();
        erpAccountsReceivable.setOddNo(erpSale.getSaleOdd());
        erpAccountsReceivable.setOddType(1);
        erpAccountsReceivable.setBusinessId(erpSale.getCustomerId());
        ErpAccountsReceivableVo erpAccountsReceivableVo = erpAccountsReceivableMapper.selectErpAccountsReceivableByQueryWhere(erpAccountsReceivable);
        if(null != erpAccountsReceivableVo){
            erpAccountsReceivableVo.setFlag("N");//关闭应付账款
            erpAccountsReceivableMapper.updateErpAccountsReceivable(erpAccountsReceivableVo);

            ErpOutboundVo erpOutboundVo = erpOutboundMapper.selectErpOutboundByReceivableId(erpAccountsReceivableVo.getReceivableId());
            if(null != erpOutboundVo){
                erpOutboundVo.setFlag("N");//关闭出库单
                erpOutboundMapper.updateErpOutbound(erpOutboundVo);
            }
        }
        ErpSale erpSaleObj = erpSaleMapper.selectErpSaleBySaleId(erpSale.getSaleId());
        erpSaleObj.setSaleStatus(5L);//已取消
        erpSaleObj.setCancelTime(DateUtils.getNowDate());//取消时间
        return erpSaleMapper.updateErpSale(erpSaleObj);
    }
}
